<template>
  <div id="editor-container">
    <Toolbar style="height: 41px; border-bottom: 1px solid #ddd" :editor="editorRef" :defaultConfig="toolbarConfig" />
    <Editor style="height: 150px; overflow: auto" v-model:modelValue="valueHtml" :defaultConfig="editorConfig"
      @onChange="handleChange" @onCreated="handleCreated" />
  </div>
</template>

<script setup lang="ts">
import "@wangeditor/editor/dist/css/style.css"; // 引入 css
import {
  onBeforeUnmount,
  ref,
  onMounted,
  shallowRef,
  watchEffect,
  watch,
  defineEmits,
  defineProps,
} from "vue";
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import { ElMessage } from "element-plus";

// 声明属性-当父组件传递数据发生变化时触发
const props = defineProps<{ modelValue: string }>();

// 声明事件消息-当valueHtml发生变化时触发
const emit = defineEmits<(e: "update:modelValue", value: String) => void>();

//Editor实例
const editorRef = shallowRef();
//内容HTML
const valueHtml = ref("");
// 监听父组件数据变化
watchEffect(() => {
  valueHtml.value = props.modelValue;
});

// 监听子组件数据变化
watch(valueHtml, (newHtml) => {
  emit("update:modelValue", newHtml);
});

//工具配置:保留需要的工具
const toolbarConfig = { toolbarKeys: ["uploadImage"] };
// toolbarConfig.toolbarKeys = ["uploadImage"];
// 内容配置
const editorConfig = {
  placeholder: "请输入内容...",
  showLinkImg: false,
  scroll: true,
  // 上传图片配置
  MENU_CONF: {
    uploadImage: {
      server: "/saferycom/file/upload_file",
      fieldName: "file",
      allowedFileTypes: ["image/*"],
      uploadImgMaxSize: 10 * 1024 * 1024, // 设置图片最大上传大小为10MB
      maxFileSize: 10 * 1024 * 1024, // 设置文件大小限制为10MB
      customInsert: async (res: any, insertFn: any) => {
        if (res.code === 200) {
          // 这里的res.data.filePath为localhost的地址，需要将前缀转换为服务器地址
          // const serverUrl = import.meta.env.VITE_SERVE;
          // const imageUrl = res.data.filePath.split(":8888")[1];
          // const filePath = serverUrl.trimEnd() + imageUrl;
          insertFn(res.data.resultFilePath); //上传到服务器
        } else {
          ElMessage.error("上传图片失败");
          throw new Error();
        }
      },
      customPaste: async (editor:any, event:any) => {
        const items = event.clipboarData.items;
        for (let item of items) {
          if(item.kind === 'file' && item.type.startsWith('image/')) {
            const file = item.getAsFile();
            const formData = new FormData();
            formData.append('file', file);
            fetch("/saferycom/file/upload_file", {
              method: "POST",
              body: formData,
            })
            .then(response => response.json())
            .then(result => {
              editor.cmd.do('insertHtml',`<img src="${result.resultFilePath}"/>`);
            })
            .catch(error => {
              ElMessage.error("粘贴图片上传失败",error);
              event.preventDefault();
            });
          }
        }
        event.preventDefault();
        return false;
      },
    },
  },
};

// 编辑器回调函数
const handleCreated = (editor: any) => {
  editorRef.value = editor; //记录editor实例
};

const handleChange = (editor: any) => {
  // emit("update:modelValue", editor.getHtml());
  const data = editor.getHtml();

  // 解析HTML字符串为DOM
  const parser = new DOMParser();
  const doc = parser.parseFromString(data, 'text/html');

  // 获取所有的img标签
  const images = doc.querySelectorAll('img');

  // 为每个img标签添加style属性
  images.forEach(img => {
  img.setAttribute('style', 'width: 30%;');
  });

  // 将修改后的DOM转换回字符串
  const modifiedData = doc.body.innerHTML;

  emit("update:modelValue", modifiedData);
};

// 模拟异步获取内容
onMounted(() => {
  setTimeout(() => {
    valueHtml.value = props.modelValue ?? ""; //回显父组件穿过来的数据，有就显示，没有就为空
  }, 300);
});

// 组件销毁时销毁编辑
onBeforeUnmount(() => {
  const editor = editorRef.value;
    if (editor == null) return;
    editor.destroy();
  });
</script>

<style scoped lang="scss">
#editor-container {
  width: 622px;
  height: 200px;
  border: 1px solid #ddd;
}

.w-e-text-container blockquote,
.w-e-text-container li,
.w-e-text-container p,
.w-e-text-container td,
.w-e-text-container th,
.w-e-text-toolbar * {
  line-height: unset !important;
}
</style>
